<template>
  <div class="addr-item" :title="title">
    <el-cascader
      ref="refDom"
      :props="props"
      :placeholder="getDataLoading ? '获取地址中' : '请选择地址'"
      clearable
      v-model="addrs"
      @change="addrsChange"
      :disabled="getDataLoading"
    />
  </div>
</template>

<script setup lang="ts">
  import { ref, onUpdated, onMounted, watch } from 'vue'
  import type { CascaderProps } from 'element-plus'
  import { getPrimaryAddress, getSecondAddress, getAddressLevel } from '@/api/address'

  const addrLevel = ref(1) // 地址层级 1-四级 2-三级

  const addrs = ref([]) // 地址 code
  const provinces = ref([]) // 省
  const citys = ref([]) // 市
  const areas = ref([]) // 区/县
  const towns = ref([]) // 镇
  const addrLabels = ref([]) // 地址对象
  const title = ref()
  const emit = defineEmits(['value-change'])
  //子组件接收父组件传递过来的值
  const reProps = defineProps({
    addrs_data: Object,
    no_level: Boolean,
    checkStrictly: Boolean,
  })

  // 清空地址
  const clearValue = () => {
    addrs.value = []
  }

  // 获取地址层级
  const getLevel = () => {
    if (reProps.no_level) {
      return
    }
    getAddressLevel().then((res) => {
      addrLevel.value = res.data.data.row
    })
  }

  // 渲染的数据
  const renData = (level, data: any, resolve) => {
    const nodes = data.map((item) => ({
      value: item.code,
      label: item.name,
      leaf: addrLevel.value == 1 ? level >= 3 : level >= 2,
    }))
    resolve(nodes)
  }

  // 获取地址
  // lazyLoad加载过数据后就不再调用，比如：第一次切换到北京市后再切换到北京市lazyLoad就不再调用，导致了数据不准确的问题
  // 建议通过value-change事件来拿地址
  const props: CascaderProps = {
    lazy: true,
    lazyLoad(node, resolve) {
      let level = node.level
      if (level == 0) {
        getPrimaryAddress().then((res) => {
          if (res.data.success) {
            provinces.value = res.data.data.rows
            renData(level, res.data.data.rows, resolve)
          }
        })
      }
      if (node.value != undefined) {
        getSecondAddress(node.value).then((res) => {
          if (level == 1) {
            // 获取======>>> 市
            citys.value = res.data.data.rows
            renData(level, citys.value, resolve)

            // 将用户选择的省保存下来
            addrLabels.value = []
            provinces.value.forEach((item) => {
              if (item.code == node.value) {
                addrLabels.value.push(item.name)
              }
            })
          }
          if (level == 2) {
            // 获取======>>> 县/区
            areas.value = res.data.data.rows
            renData(level, areas.value, resolve)
            addrLabels.value = addrLabels.value.splice(0, 1)

            // 将用户选择的市保存下来
            citys.value.forEach((item) => {
              if (item.code == node.value) {
                addrLabels.value.push(item.name)
              }
            })
          }
          if (level == 3) {
            // 获取======>>> 镇
            towns.value = res.data.data.rows
            renData(level, towns.value, resolve)
            addrLabels.value = addrLabels.value.splice(0, 2)

            // 将用户选择的区保存下来
            areas.value.forEach((item) => {
              if (item.code == node.value) {
                addrLabels.value.push(item.name)
              }
            })
          }
        })
      }
    },
    checkStrictly: reProps.checkStrictly,
  }

  // 封装返回需要的对象
  const getLabel = () => {
    if (addrs.value == null) {
      return
    }
    if (addrLevel.value == 1) {
      //  四级
      addrLabels.value = addrLabels.value.splice(0, 3)
      towns.value.forEach((item) => {
        if (item.code == addrs.value[addrs.value.length - 1]) {
          addrLabels.value.push(item.name)
        }
      })
      return {
        province: addrLabels.value[0] == undefined ? '' : addrLabels.value[0],
        city: addrLabels.value[1] == undefined ? '' : addrLabels.value[1],
        area: addrLabels.value[2] == undefined ? '' : addrLabels.value[2],
        town: addrLabels.value[3] == undefined ? '' : addrLabels.value[3],
      }
    } else {
      //  三级
      addrLabels.value = addrLabels.value.splice(0, 2)
      areas.value.forEach((item) => {
        if (
          item.code == addrs.value[addrs.value.length - 1] &&
          addrLabels.value.indexOf(item.name) == -1
        ) {
          addrLabels.value.push(item.name)
        }
      })

      return {
        province: addrLabels.value[0] == undefined ? '' : addrLabels.value[0],
        city: addrLabels.value[1] == undefined ? '' : addrLabels.value[1],
        area: addrLabels.value[2] == undefined ? '' : addrLabels.value[2],
        town: addrLabels.value[3] == undefined ? '' : addrLabels.value[3],
      }
    }
  }

  // 获取数据加载状态
  const getDataLoading = ref(false)

  // 封装数据回显的方法
  const dataEcho = async () => {
    if (!reProps.addrs_data) {
      return
    } else {
      getDataLoading.value = true
      const res = await getPrimaryAddress()
      if (res.data.success) {
        res.data.data.rows.forEach((item) => {
          if (item.name == reProps.addrs_data.province) {
            if (!addrs.value.includes(item.code)) {
              addrs.value.push(item.code)
            }
          }
        })
      }
      if (addrs.value[0]) {
        const res = await getSecondAddress(addrs.value[0])
        res.data.data.rows.forEach((item) => {
          if (item.name == reProps.addrs_data.city) {
            if (!addrs.value.includes(item.code)) {
              addrs.value.push(item.code)
            }
          }
        })
      }
      if (addrs.value[1]) {
        const res = await getSecondAddress(addrs.value[1])
        res.data.data.rows.forEach((item) => {
          if (item.name == reProps.addrs_data.area) {
            if (!addrs.value.includes(item.code)) {
              addrs.value.push(item.code)
            }
          }
        })
      }
      if (addrs.value[2] && addrLevel.value == 1) {
        const res = await getSecondAddress(addrs.value[2])
        res.data.data.rows.forEach((item) => {
          if (item.name == reProps.addrs_data.town) {
            if (!addrs.value.includes(item.code)) {
              addrs.value.push(item.code)
            }
          }
        })
      }
      getDataLoading.value = false
    }
  }
  let refDom = ref()

  // 绑定值发生变化
  const addrsChange = () => {
    let tem = refDom.value.inputValue.split('/ ')
    let result = {
      province: tem[0]?.trim(),
      city: tem[1]?.trim() || '',
      area: tem[2]?.trim() || '',
      town: tem[3]?.trim() || '',
    }
    emit('value-change', result)
  }

  defineExpose({ getLabel, dataEcho, clearValue })

  onMounted(async () => {
    getLevel()
    if (reProps.addrs_data) {
      await dataEcho()
      if (addrLevel.value == 1) {
        title.value =
          reProps.addrs_data.province +
          '-' +
          reProps.addrs_data.city +
          '-' +
          reProps.addrs_data.area +
          '-' +
          reProps.addrs_data.town
      } else {
        title.value =
          reProps.addrs_data.province +
          '-' +
          reProps.addrs_data.city +
          '-' +
          reProps.addrs_data.area
      }
    }
  })

  // 用标题显示地址
  onUpdated(() => {
    if (getLabel() == undefined) {
      return
    }
    if (addrLevel.value == 1) {
      title.value =
        getLabel().province + '-' + getLabel().city + '-' + getLabel().area + '-' + getLabel().town
    } else {
      title.value = getLabel().province + '-' + getLabel().city + '-' + getLabel().area
    }
  })

  // 监听地址变化
  watch(
    () => reProps.addrs_data,
    (newVal) => {
      if (newVal.province) {
        addrs.value = []
        dataEcho()
      }
    },
    { immediate: true },
  )
</script>

<style scoped lang="scss">
  .addr-item {
    width: 200px;
    display: flex;
    align-items: center;
  }
</style>
